package com.most.security;

import com.most.api.UserClient;
import com.most.redis.RedisUtil;
import com.most.util.JwtUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 自定义Realm
 */
public class TokenRealm extends AuthorizingRealm {

    @Autowired
    RedisUtil redisUtil;
    @Autowired
    UserClient userClient;
    @Override
    public boolean supports(AuthenticationToken token) {
        //这个token就是从过滤器中传入的jwtToken
        return token instanceof StatelessAuthToken;
    }
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        String userId = (String)principals.getPrimaryPrincipal();
        List<String> permissions = userClient.getPermissionsById(Long.valueOf(userId));
        if (CollectionUtils.isEmpty(permissions)) {
            throw new AuthorizationException();
        }
        //3.对权限标识信息进行封装
        Set<String> stringPermissions = new HashSet<>();
        for (String per : permissions) {
            if (!StringUtils.isEmpty(per)) {
                stringPermissions.add(per);
            }
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(stringPermissions);
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String tokenPrincipal = (String) token.getPrincipal();
        String userName = JwtUtils.getUserName(tokenPrincipal);
        String userKey = JwtUtils.getUserKey(tokenPrincipal);
        String userId = JwtUtils.getUserId(tokenPrincipal);
        Object userKeyRedis = redisUtil.get(userName);
        if (userKeyRedis==null){
            throw new AuthorizationException("登陆状态已过期！");
        }
        if (!userKey.equals(userKeyRedis .toString())){
            throw new AuthorizationException("登陆状态已过期！");
        }
        return new SimpleAuthenticationInfo(userId,tokenPrincipal, this.getName());
    }
}